package com.obs.config;

import cn.hutool.core.util.IdUtil;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.CreateBucketRequest;
import com.google.common.collect.ImmutableSet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Set;

@Configuration
@Slf4j
public class S3Config {

    private static final Set<String> IGNORED_ERROR_CODES = ImmutableSet.of(
            "BucketAlreadyExists", "BucketAlreadyOwnedByYou"
    );

    @Autowired
    private S3Properties s3Properties;

    /**
     * OSS 置为 false
     */
    @Value("${s3.access.enabled:false}")
    private boolean pathStyleAccess;

    @Bean
    public AmazonS3 client() {
        AWSCredentials credentials = new BasicAWSCredentials(s3Properties.getAccessKey(), s3Properties.getSecretKey());
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        clientConfiguration.setSignerOverride("AWSS3V4SignerType");
        clientConfiguration.setMaxConnections(100);
        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                //此处的region配置必须是cn-north-1，其他的会报错：The location constraint is incompatible for the region specific endpoint this request was sent to
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(s3Properties.getEndpoint(), Regions.CN_NORTH_1.name()))
                .withPathStyleAccessEnabled(pathStyleAccess)
                .withClientConfiguration(clientConfiguration)
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .disableChunkedEncoding()
                .build();
        String bucketName = s3Properties.getBucketName();
        if (s3Client.doesBucketExistV2(bucketName)) {
            log.info("s3 桶 {} 已存在,不需要新建", bucketName);
        } else {
            try {
                Bucket bucket = s3Client.createBucket(new CreateBucketRequest(bucketName));
                log.info("S3 bucket created: {}", bucket);
            } catch (AmazonServiceException e) {
                if (IGNORED_ERROR_CODES.contains(e.getErrorCode())) {
                    log.warn("忽略 s3 创建桶 {} 异常", bucketName, e);
                } else {
                    throw e;
                }
            }
        }

        return s3Client;
    }
}
